package org.wmine.algo;

import java.awt.Button;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;


public class FPTree extends JFrame
{

/*	int goalIndex;int rowCnt;
	String [][] data4;double [] gains;
	Vector vName;
	int i;String classLbl;
	//final JCheckBox [] cb111;
*/	 
	JRadioButton [] rb;
	ButtonGroup bg=new ButtonGroup();
	int [] selected;
	String[]attribs1;
	int colknt1,cntRow1;
	String[][]data2;
	int AttribIndex=-1;//Column Number having list of item sets
	Vector itemID;
	Vector itemCnt;
	int vecPtr;
	JTree tree;
	DefaultMutableTreeNode root;	
	public FPTree(final String[]attribs,final int colknt,final int cntRow,final String [][] data)
	{
		itemID=new Vector();
		itemCnt=new Vector();
		vecPtr=0;
		
		
		
		//System.out.println("Entered");
			attribs1=attribs;//column Names
			colknt1=colknt;//number of columns
			cntRow1=cntRow;// number of rows
			data2=data;// 2d array
			rb=new JRadioButton[colknt1];
			//bg.add()
			final Container c=this.getContentPane();
			this.setTitle("Select the Attributes");
		
			JPanel mainPanel=new JPanel();
			mainPanel.setLayout(new GridLayout(colknt+3,1));
			mainPanel.add(new JLabel("Select the attributes to be considered:"));
			//mainPanel.add(new JLabel(""));
			//cb111=new JCheckBox[colknt];
			//checkCnt=new int[colknt];
			
			
			ActionListener listener=new ActionListener(){public void actionPerformed(ActionEvent ae){update();}};
			
			for(int i = 0;i<colknt;i++)
			{
			//	cb111[i]=new JCheckBox(attribs[i]);
				//cb111[i].addActionListener(listener);
				//mainPanel.add(cb111[i]);
				rb[i]=new JRadioButton(attribs[i]);
				bg.add(rb[i]);
				rb[i].addActionListener(listener);
				mainPanel.add(rb[i]);
			}
			rb[0].setSelected(true);
			selected=new int[rb.length];
			mainPanel.add(new JLabel(""));
			JButton but1=new JButton("OK");
			but1.setBounds(10,45,110,20);
			mainPanel.add(but1);
			but1.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent ae)
			{
				dispose();
				//System.out.println("Great");
				for(int s=0;s<rb.length;s++)	//get(s);
					if(rb[s].isSelected())
						AttribIndex=s;
				//System.out.println(""+AttribIndex);
				buildFPTree();
				//clustering sd=new clustering(attribs1,colknt1,cntRow1,data2,selected);
				//sd.setBounds(350,300,310,180);
				//sd.setVisible(true);
			}});
			c.add(mainPanel);
			this.setBounds(300,200,300,(35*(colknt+1)));
		
		}
	void update()	{}
	void buildFPTree()
	{
		//DefaultMutableTreeNode country;
		DefaultMutableTreeNode root  = new DefaultMutableTreeNode("null");
	   	  //for(int k=0;k<v.size();k++)
	   	  //{
	   		//  country  = new DefaultMutableTreeNode(v.elementAt(k).toString());
	   		  //root.add(country);
	   	  //}  
	      JTree tree = new JTree(root);
   //}
   
		for(int rec=0;rec<cntRow1;rec++)
		{
			String rule=data2[rec][AttribIndex];
			StringTokenizer st=new StringTokenizer(rule," ");
			//Vector tokens=new Vector();
			
			System.out.print("\n"+st.countTokens());
			while(st.hasMoreElements())
			{
				String s=st.nextToken();
				System.out.print(s+",");
				//update  count of it
				int flag=0;
				for(int i=0;i<itemID.size();i++)
				{
					if(s.equals(itemID.elementAt(i)))
					{
						int cnt=Integer.parseInt(itemCnt.elementAt(i).toString());
						cnt++;
						flag=1;
						itemCnt.setElementAt(""+cnt,i);
						break;
					}
				}
				if(flag==0)
				{
					itemID.insertElementAt(s,vecPtr);
					itemCnt.insertElementAt("1",vecPtr++);
				}
			}
		}
	//	System.out.println("\n"+itemID+" >> "+itemCnt);
		//sort it now in decreasing order!
		for(int i=0;i<(vecPtr-1);i++)
		{
			for(int j=i+1;j<vecPtr;j++)
			{
				int i1=Integer.parseInt(itemCnt.elementAt(i).toString());
				int j1=Integer.parseInt(itemCnt.elementAt(j).toString());
				String i2=itemID.elementAt(i).toString();
				String j2=itemID.elementAt(j).toString();
				
				if(i1<j1)//swap
				{
					itemCnt.setElementAt(i1,j);
					itemCnt.setElementAt(j1,i);
					
					itemID.setElementAt(i2,j);
					itemID.setElementAt(j2,i);					
				}
			}
		}
	//	System.out.println("\n"+itemID+" >> "+itemCnt);
		//Now the aim is to consider each and every transaction t,
		//string tokenizer applied on t
		//sort it  internally according to its itemCnt place store in a vector in descending order
//		//place that vector in a string with delimeter ',' no need!!
		//call vector(that vector)
		for(int rec=0;rec<cntRow1;rec++)
		{
			String rule=data2[rec][AttribIndex];
			StringTokenizer st=new StringTokenizer(rule," ");
			Vector v1=new Vector();
			Vector v2=new Vector();
			int ind=0;
			while(st.hasMoreElements())
			{
				String s=st.nextToken();
				System.out.print(s+",");
				v1.insertElementAt(s,ind);
				//update  count of it
				for(int i=0;i<itemID.size();i++)
				{
					if(s.equals(itemID.elementAt(i)))
					{
						v2.insertElementAt(i+"",ind++);
						break;
					}
				}				
			}
			//sort
//			sort it now in increasing order!
			for(int i=0;i<v2.size()-1;i++)
			{
				for(int j=i+1;j<v2.size();j++)
				{
					int i1=Integer.parseInt(v2.elementAt(i).toString());
					int j1=Integer.parseInt(v2.elementAt(j).toString());
					String i2=v1.elementAt(i).toString();
					String j2=v1.elementAt(j).toString();
					
					if(i1>j1)//swap
					{
						v1.setElementAt(i2,j);
						v1.setElementAt(j2,i);
						v2.setElementAt(i1,j);
						v2.setElementAt(j1,i);
					}
				}
			}
			System.out.println(v1+" **********************************");
			 /*Enumeration e1=root.children();
			 System.out.println(root.isLeaf()+" "+root.getUserObject()+" "+e1.hasMoreElements());
			 if(!e1.hasMoreElements())
			 {
				 //root.
				 String child=v1.elementAt(0).toString()+"=1";
				 root.add(new DefaultMutableTreeNode(child));
				 
			 }
			 else
			 {	
				 Enumeration e=root.breadthFirstEnumeration();
				 if(e.hasMoreElements())
				 {
					  DefaultMutableTreeNode node=(DefaultMutableTreeNode)e.nextElement();
					  System.out.println(node+","+v1.elementAt(0).toString());
					   //if(node.getUserObject().toString().equals(v1.elementAt(0).toString()))
					   {
						   System.out.println(node.getUserObject().toString());
					   }
					   break;
				 }
				 
				 
			 }*/
			//callVector(v1,root,0);
			//call(root);
		}
		//call(root);
		
	}


 public void callVector(Vector vpath,DefaultMutableTreeNode node,int vpathInd)
   {
//insert that for root
			   Enumeration e1=node.children();
			 //  System.out.println(node.isLeaf()+" "+node.getUserObject());
			   int flg=0;
			   if(node.isLeaf()&&node.getUserObject().toString().equals("null"))
			   {
				   System.out.println("its a root so adding for the first time");
				   while(vpathInd<vpath.size())
				   {
					   System.out.println("Adding .."+vpath.elementAt(vpathInd));
					   node.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
					   node=(DefaultMutableTreeNode)node.getChildAt(0);
					  // System.out.println(node.isLeaf()+"+++++++++++++++++++");
				   }
				//   System.out.println(">>>>>>>>>>>>>>>>. "+node.getPath().toString());
				   return;				   
			   }
			
			   else
				   if(!node.isLeaf()&&node.getUserObject().toString().equals("null"))
				   {
					   vpathInd=0;
					   int got1=0;
					   e1=node.children();
					   System.out.println("The tree has leaves,but we are at the root "+node.getChildCount());
					   while(e1.hasMoreElements())
					   {
						   DefaultMutableTreeNode df=(DefaultMutableTreeNode)e1.nextElement();
						   if(df.getUserObject().toString().equals(vpath.elementAt(vpathInd).toString()))
						   {
							   System.out.println("Already branched"+ vpath.elementAt(vpathInd).toString()+df.getChildCount());
							   if(df.isLeaf())
							   {
							 while(vpathInd<vpath.size())
						   	{
							   System.out.println("adding"+(vpath.elementAt(vpathInd)));
							   df.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
							   df=(DefaultMutableTreeNode)df.getChildAt(0);
							   got1=1;
						  // System.out.println(node.isLeaf()+"+++++++++++++++++++");
						   	}
							 return;
							   }
							   else
							   {
								   System.out.println("Already branched...have to enumerate");
								   Enumeration chi=df.children();
								   callEnum(chi,vpath,1);
								   got1=1;
								   return;
							   }
								   
							   
						   }
						   else
							   if(!df.getUserObject().toString().equals(vpath.elementAt(vpathInd).toString()))
							   {
								   System.out.println("searching!!!");
								   ;//go ahead
							   }
						   	   
					   }
					   if(got1==0)
					   {
						   System.out.println("Not branched");
						   vpathInd=0;
						  // node=root;
						   while(vpathInd<vpath.size())
						   {
							  System.out.println("adding"+(vpath.elementAt(vpathInd)));
							
							   node.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
							   System.out.println("added");
							   node=(DefaultMutableTreeNode)node.getFirstChild();//getChildAt(0);
							  // System.out.println(node.isLeaf()+"+++++++++++++++++++");
						   }
						   return;
					   }
					   return;
				   }
			   else
			   {
				   System.out.println("Iterate through the children of the root");
				   callEnum(e1,vpath,vpathInd);
			   }

		
	}
   
 public void callEnum(Enumeration e1,Vector vpath,int vpathInd)
 {
	
	int flgGot=0;
	DefaultMutableTreeNode node1=new DefaultMutableTreeNode();
	DefaultMutableTreeNode tempNode=new DefaultMutableTreeNode();//=(DefaultMutableTreeNode)e1.nextElement();
	   while(e1.hasMoreElements())
	   {
		   System.out.println("coming2");
		   node1=(DefaultMutableTreeNode)e1.nextElement();
		   tempNode=node1;
		   System.out.println(node1.getUserObject().toString()+" >> "+vpath.elementAt(vpathInd));
		   if(node1.getUserObject().toString().equals(vpath.elementAt(vpathInd).toString()))
		   {
			   if(node1.isLeaf())
			   {
				   System.out.println("adding to leaf"+vpathInd);
				   vpathInd++;
			   while(vpathInd<vpath.size())
			   {
			
				   node1.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
				   node1=(DefaultMutableTreeNode)node1.getChildAt(0);
			//	   System.out.println(node1.isLeaf()+"+++++++++++++++++++");
				   flgGot=1;
			   }
			   flgGot=1;
			   return;//break;
			   }
			   else
			   {
				   //Enumeration subnodes=n
				   System.out.println("will add to non leaf"+vpathInd+1+" "+node1.getChildAt(0));
				   callEnum(node1.children(),vpath,vpathInd+1);
				   return;//break;
			   }
			   
		   }
		   else
		   {//simply go to next child now!
			  /* if((!node1.isLeaf())&&node1.getUserObject().toString().equals(vpath.elementAt(vpathInd-1).toString()))
			   {
				   System.out.println("iterating!!!!!");
				   callEnum(node1.children(),vpath,vpathInd+1);
			   }
			   else
			 if(!node1.getUserObject().toString().equals(vpath.elementAt(vpathInd-1).toString()))
			   {
				 //System.out.println(" At least here"+vpath.elementAt(vpathInd-1).toString()+">>"+vpath.elementAt(vpathInd).toString());
		//		 System.out.println(" At least here"+vpathInd);  
				 DefaultMutableTreeNode parent=(DefaultMutableTreeNode)node1.getParent();
				   parent.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
				   DefaultMutableTreeNode node2=(DefaultMutableTreeNode)parent.getChildAfter(node1);
				   while(vpathInd<vpath.size())
				   {
					   node2.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
					   node2=(DefaultMutableTreeNode)node2.getChildAt(0);
					   System.out.println("adding"+node2.getUserObject());
					   flgGot=1;
				   }
			
				   break;
			   }*/
		   }
		
	   }
	   
	  System.out.println("Got ?"+flgGot+" index"+vpathInd);
	  if(flgGot==0)
	  {
		  DefaultMutableTreeNode parent=(DefaultMutableTreeNode)tempNode.getParent();
		  parent.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
		   System.out.println(vpath.size()+"Added "+vpath.elementAt(vpathInd-1));
		  DefaultMutableTreeNode node2=(DefaultMutableTreeNode)parent.getChildAfter(tempNode);
		  while(vpathInd<vpath.size())
		  {
			   node2.add(new DefaultMutableTreeNode(vpath.elementAt(vpathInd++)));
			   node2=(DefaultMutableTreeNode)node2.getChildAt(0);
			   System.out.println("adding"+node2.getUserObject());
			   flgGot=1;
		   }
	return;
		
		  
	  }
	  //break;
	//}
 }

 public void call(DefaultMutableTreeNode node)
{
	Enumeration e= node.children();
	while(e.hasMoreElements())
	{
		DefaultMutableTreeNode node11=(DefaultMutableTreeNode)e.nextElement();
		System.out.print(node11.getUserObject().toString()+" =>");
		call(node11);
	}
	
	
	}
   }